# Copyright (c) 2017 Presto Labs Pte. Ltd.
# Author: inkyu

import ujson as json

from coin.base.book.types import TradeSide, create_market_trade_event
from coin.exchange.base.ws.handler import WebsocketHandler
from coin.exchange.binance.book_builder import BinanceBookBuilder as BookBuilder
from coin.exchange.binance.ws.handler import SpotTraits


class BinanceSnapshotHandler(WebsocketHandler):
  def on_ws_book(self, record, queue_data, topic_data):
    data = record.data
    if not isinstance(data, dict) and not isinstance(data, list):
      data = json.loads(data.tobytes())
    symbol = data['stream'].split('@')[0].upper()
    data = data['data']

    book = BookBuilder(symbol, 0, book_builder_observer=self._book_builder_observer)
    self._books[symbol] = book
    assert 'bids' in data
    assert 'asks' in data
    bids = data['bids']
    asks = data['asks']
    book.snapshot(bids, asks)
    book.update_timestamp(record.timestamp)
    book.update_topic_id(record.topic_id)
    self.ready = True
    product = SpotTraits.get_product_from_symbol(symbol, record.timestamp)
    if self._feed_checker:
      self._feed_checker.on_book(product=product, book=book, timestamp=record.timestamp)
    self.publish_event('book', book.symbol, book)
    book.reset_observer()

  def on_ws_trade(self, record, queue_data, topic_data):
    data = record.data
    if not isinstance(data, dict):
      data = json.loads(data.tobytes())
    if 'data' in data:
      data = data['data']
    event = data['e']
    assert event == 'trade'
    symbol = data['s']
    if not self.is_subscribed('trade', symbol):
      return
    price = float(data['p'])
    qty = float(data['q'])
    side = TradeSide.TRADE_SELL_SIDE if data['m'] else TradeSide.TRADE_BUY_SIDE
    trade_event = create_market_trade_event(record.timestamp,
                                            symbol,
                                            price,
                                            qty,
                                            side,
                                            topic_id=record.topic_id)
    product = SpotTraits.get_product_from_symbol(symbol, record.timestamp)
    if self._feed_checker:
      self._feed_checker.on_trade(product=product,
                                  trade_event=trade_event,
                                  timestamp=record.timestamp)
    self.publish_event('trade', symbol, trade_event)

  # Deprecated
  on_ws = on_ws_book
  on_trade = on_ws_trade
